package com.baomidou.mybatisplus.config;

import com.baomidou.dynamic.datasource.aop.DynamicDatasourceNamedInterceptor;
import com.baomidou.dynamic.datasource.processor.DsProcessor;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * DynamicDatasource多数据源配置
 * 使用这个方式，原注解方式并不会失效。
 * 注意：不要在同一个切面同时使用注解又使用自定义切面。
 *
 * 实现项目service下所有类与mybatisPlus框架中serviceImpl中
 * add等开头的方法使用master数据源，
 * select等开头的方法使用slave数据源。
 *
 * @author Jerry.Zeng
 * @date 2021/11/3
 */
@Configuration
public class MyDynamicDatasourceConfig {

    @Bean
    public DynamicDatasourceNamedInterceptor dsAdvice(DsProcessor dsProcessor) {
        DynamicDatasourceNamedInterceptor interceptor = new DynamicDatasourceNamedInterceptor(dsProcessor);
        Map<String, String> patternMap = new HashMap<>();
        // 设置从库
        patternMap.put("select*", "slave");
        patternMap.put("find*", "slave");
        patternMap.put("get*", "slave");
        patternMap.put("query*", "slave");
        patternMap.put("list*", "slave");
        patternMap.put("count*", "slave");
        patternMap.put("exist*", "slave");
        patternMap.put("search*", "slave");
        // 设置主库
        patternMap.put("add*", "master");
        patternMap.put("save*", "master");
        patternMap.put("update*", "master");
        patternMap.put("delete*", "master");
        interceptor.addPatternMap(patternMap);
        return interceptor;
    }

    @Bean
    public Advisor dsAdviceAdvisor(DynamicDatasourceNamedInterceptor dsAdvice) {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution (* com.baomidou.mybatisplus.service..*(..))" +
                " or execution(* com.baomidou.mybatisplus.extension.service..*(..))");
        return new DefaultPointcutAdvisor(pointcut, dsAdvice);
    }

}